/*
 * @(#)AutoTigAIWorkflow.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.customize.workflow.action;

import java.sql.Connection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobDataMap;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.workflow.action.AutoTaskTemplate;
import com.dcivision.workflow.bean.MtmWorkflowChildParentProgress;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.core.WorkflowProcessor;
import com.dcivision.workflow.core.WorkflowProgressManager;
import com.dcivision.workflow.dao.MtmWorkflowChildParentProgressDAObject;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;
import com.dcivision.workflow.web.MaintWorkflowRecordForm;

/**
 * This is a class that acts as a template for coding automatic task to trigger
 * sub-workflow. Similar as in AutoTaskTemplate, you may need to define the
 * number of routine. For trigger sub-workflow, you may also need to define if
 * this is parent-dependent, if yes, the parent progress will be waken up after
 * current progress is finished.
 * 
 * If the trigger sub-workflow is parent-dependent, you may also set the status
 * of current progress to PENDING by,
 * 
 * <pre>
 *   this.currentProgressStatus = WorkflowProgress.STATUS_PENDING;
 * </pre>
 * 
 * Currently, you need to hardcode the sub-workflow ID inside your program, but
 * you may also somehow store it in properties file or database table. In order
 * to start the sub-workflow, you may need to construct the
 * MaintWorkflowRecordForm object first and use the WorkflowProgressManager to
 * start the track:
 * 
 * <pre>
 *   WorkflowRecord workflowRecord = (WorkflowRecord) recordDAO.getObjectByID(this.subworkflowRecordID);
 *   MaintWorkflowRecordForm recordForm = new MaintWorkflowRecordForm();
 *   recordForm.setFormData(workflowRecord);
 *   WorkflowProgress workflowProgress = (WorkflowProgress) progressManager.startWorkflowTrack(recordForm);
 * </pre>
 * 
 * If it is parent-dependent and need to wake up the parent after the
 * sub-workflow finished, you may also required to create an parent-child
 * relationship by,
 * 
 * <pre>
 * if (this.parentDependent) {
 *   MtmWorkflowChildParentProgress childWorkflowParentProgress = new MtmWorkflowChildParentProgress();
 *   childWorkflowParentProgress.setParentWorkflowProgressID(currentProgress.getID());
 *   childWorkflowParentProgress.setSubworkflowTrackID(workflowProgress.getTrackID());
 *   childWorkflowParentProgress = (MtmWorkflowChildParentProgress) subworkflowDAO.insertObject(childWorkflowParentProgress);
 * }
 * </pre>
 * 
 * For other details of properties and method call, please refer to AutoTaskTemplate
 * 
 * @author Dick Xie
 * @company DCIVision Limited
 * @creation date 31/12/2004
 * @version $Revision: 1.2.2.1 $
 * @see AutoTaskTemplate
 */
public class AutoTigAIWorkflow extends com.dcivision.workflow.core.WorkflowProcessor {

  public static final String REVISION = "$Revision: 1.2.2.1 $";

  protected Log log = LogFactory.getLog(this.getClass().getName());
  protected Integer subworkflowRecordID = new Integer(11); //* the subworkflow record id;

  public AutoTigAIWorkflow() {
    this.numOfRoutine=1;
    this.labelType = WorkflowProcessor.LABEL_TYPE_USER_DEFINE;
    this.labelString = new String[] {"workflow.label.step_status_G"};
    this.parentDependent = true;

    //* depends on whether want the subworkflow to be running independent of the parent workflow or not
    if (this.parentDependent) {
      this.currentProgressStatus = WorkflowProgress.STATUS_PENDING; //* subworkflow has close relationship with parent
    } else {
      this.currentProgressStatus = WorkflowProgress.STATUS_GENERAL_ACCOMPLISHMENT; //* subflow running independent of the parnet workflow
    }
  }

  public synchronized void execute(JobDataMap dataMap, WorkflowProgress currentProgress) throws ApplicationException {
    log.info("***** AutoTaskStartSubWorkflowTemplate workflow processor BEGIN *****");
    this.bCreateNextWorkflowProgress=true;
    Connection conn = null;

    try {
      //* get the DB Connection
      conn = DataSourceFactory.getConnection();
      SessionContainer sessionCon = this.getSessionContainer();

      //* create required DAObject
      WorkflowRecordDAObject recordDAO = new WorkflowRecordDAObject(sessionCon, conn);
      WorkflowProgressManager progressManager = new WorkflowProgressManager(sessionCon, conn);
      MtmWorkflowChildParentProgressDAObject subworkflowDAO = new MtmWorkflowChildParentProgressDAObject(sessionCon, conn);

      //* get relevant information from
      //AbstractBaseObject workflowObject = (AbstractBaseObject) dataMap.get("WORKFLOW_OBJECT");
      //log.debug("workflow object class name: "+workflowObject.getClass().getName());
      //Integer docID = workflowObject.getID();

      log.info("current progress' workflow step id: "+currentProgress.getWorkflowStepID());
      Integer userRecordID = currentProgress.getUpdaterID();
      UserRecordDAObject userDAO = new UserRecordDAObject(sessionCon, conn);
      log.info("userRecordID: "+userRecordID);
      UserRecord userRecord = (UserRecord) userDAO.getObjectByID(userRecordID);
      sessionCon.setUserRecord(userRecord);

      this.subworkflowRecordID=new Integer(9);
      
      //* do what you want below
      WorkflowRecord workflowRecord = (WorkflowRecord) recordDAO.getObjectByID(this.subworkflowRecordID );
      MaintWorkflowRecordForm recordForm = new MaintWorkflowRecordForm();
      recordForm.setFormData(workflowRecord);
      Integer autoUserID=progressManager.getAutoTaskActorUser(currentProgress);
      log.debug("start workflow start new track");
      WorkflowProgress workflowProgress = (WorkflowProgress) progressManager.startWorkflowTrack(recordForm,autoUserID);
      log.debug("end workflow start new track");

      if (this.parentDependent) {
        log.debug("add workflow child parent progress record");
        MtmWorkflowChildParentProgress childWorkflowParentProgress = new MtmWorkflowChildParentProgress();
        childWorkflowParentProgress.setParentWorkflowProgressID(currentProgress.getID());
        childWorkflowParentProgress.setSubworkflowTrackID(workflowProgress.getTrackID());
        childWorkflowParentProgress = (MtmWorkflowChildParentProgress) subworkflowDAO.insertObject(childWorkflowParentProgress);
        log.debug("finish add workflow child parent progress record");
      }

      //* after the execution, set the desired appropriate out number
      this.returnRoutineIndex = 1; //* should be between 0 and numOfRoutine-1
      //* if need to auto-Execute the following step, set the below variable to true (default false)
      this.bAutoExecuteNextStep=false; 
      this.bCreateNextWorkflowProgress=true;

      conn.commit();
    } catch (ApplicationException appEx) {
      log.error("Application exception:\n"+appEx);
      throw appEx; //* prop
    } catch (Exception e) {
      log.error("Error during processing this automatic task.", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR); //* throw an applicationExcpetion with an appropriate
    } finally {
      try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
    }

    log.info("***** AutoTaskStartSubWorkflowTemplate workflow processor END   *****");
  }
}
